<?php
declare (strict_types=1);

namespace app\common\model;

use app\common\controller\Bonus;
use app\common\facade\Jpush;
use app\common\facade\Pay;
use app\common\tool\account\Account;
use app\common\tool\WxTpl;
use think\facade\Cache;
use think\facade\Db;
use think\facade\Event;
use think\facade\Log;
use think\model\relation\HasMany;

class OrderTemporary extends Order
{
    protected $name = 'order';

    /**
     * @param $param
     * @param $user
     * @return array
     * 设置临时下单商品
     */
    public static function setTemporary($param, $user): array
    {
        try {
            if(!$user->is_real){
                return ['code' => -1, 'msg' => '请先完成实名认证'];
            }
            if ($param['type'] == 1) {
                $result = ProductSpecValue::getSettled($param, $user);
                if ($result['code'] != 1) return $result;
                $productTemporary = $result['data'];
            } else {
                $result = ProductCart::getSettled($user, $param['cart_id']);
                if ($result['code'] != 1) return $result;
                $productTemporary = $result['data'];
            }
            if (empty($productTemporary)) {
                return ['code' => -1, 'msg' => '服务器错误，请稍后再试'];
            }

            //缓存购物车标识
            if (isset($param['cart_id']) && $param['cart_id']) {
                Cache::set('productTemporaryCartId_' . $user->id, $param['cart_id']);
            }
            //是否是生活缴费订单
            $productTemporary['is_life'] = 0;
            if (in_array(5, $productTemporary['cate_1'])) {
                if (in_array(30, $productTemporary['cate_2'])) {
                    $productTemporary['is_life'] = 1;
                } else {
                    $productTemporary['is_life'] = 2;
                }
            }
            $productTemporary['is_prize'] = isset($param['is_prize']) && $param['is_prize'] == 1 ? 1 : 0;
            $productTemporary['prize_record_id'] = isset($param['prize_record_id']) ? (int)$param['prize_record_id'] : 0;
            Cache::set('productTemporary_' . $user->id, $productTemporary);
            return ['code' => 1, 'msg' => 'success'];
        } catch (\Exception $e) {
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    /**
     * @param $uid -- 会员ID
     * @return array
     * 获得会员临时暂存的订单
     */
    public static function getTemporary($uid): array
    {
        try {
            $temporary = Cache::get('productTemporary_' . $uid);
            if (empty($temporary)) {
                return ['code' => -1, 'msg' => '加载失败，请再试一次！'];
            }
            $temporary['address'] = Address::getDefault($uid);
            return ['code' => 1, 'msg' => 'success', 'data' => $temporary];
        } catch (\Exception $e) {
            return ['code' => -1, 'msg' => '加载失败，请再试一次！'];
        }
    }

    public static function getPayment($id, $user = '',$cate_2='')
    {
        try {
            $info = parent::where('id', $id)->field('id,sn,real_amount,expire_time,status,order_type')->find();
            if ($info->getData('status') != 1) {
                return ['code' => -1, 'msg' => '订单已支付或已失效'];
            }
            $data['order'] = $info;
            $data['method'] = self::payWay($info->order_type, true, $cate_2);
            $data['assets'] = [
                'chain_bean' => $user->assets->chain_bean,
                'love_bean' => $user->assets->love_bean,
                'subsidy'   => $user->assets->subsidy,
            ];

            $data['woc'] = '';
            if (!in_array($info->order_type, [6, 7])) {
                $data['woc'] = generateCodeD(14) . 'Ai' . $info->id . '&' . $user->token . 'SL' . generateCodeD(6) . ' 拜托你帮我代付一笔￥' . $info->real_amount . '元的订单';
            }
            return ['code' => 1, 'msg' => 'success', 'data' => $data];
        } catch (\Exception $e) {
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function payWay($cate_1 = '', $behalf = true, $cate_2 = ''): array
    {
        switch ($cate_1) {
            default:
                $method = ['currency','wechat'];
        }
        $method = implode(',', $method);
        return getPaymentMethod($method);
    }

    public static function payment($param, $user): array
    {
        try {
            $info = parent::where('id', $param['id'])->find();
            if ($info->getData('status') != 1) {
                return ['code' => -1, 'msg' => '订单已支付或已失效'];
            }
            $account = $param['pay_way'];

            $level_id = 0;
            $share_url = request()->domain() . "/api/register/web.html?code=" . $user['code'];
            $share_amount = Cache::get('system')['currency_share'];

            if($user->level_id != 2 && $info->order_type == 1){
                $level_id = 2;
            }elseif ($user->level_id != 3 && $info->order_type == 2){
                $level_id = 3;
            }elseif ($user->contract_role_id == 0 && $info->order_type == 9){
                $level_id = 9;
            }

            $data = [];
            if(in_array($account, ['alipay', 'wechat'])){
                $data['level_id'] = $level_id;
                $data['share_url'] = $share_url;
                $data['share_amount'] = $share_amount;
            }

            switch ($account) {
                case "alipay":
                    $notifyUrl = 'https://' . $_SERVER['HTTP_HOST'] . '/time/callback/mallAlipay';
                    //设置参数
                    $pay = Pay::setDriver('AliPay')
                        ->basic('购买商品', $info->sn, $info->real_amount, $notifyUrl);
                    $options = $pay->create('App');

                    $data['pay_alipay'] = $options;
                    $data['pay_wechat'] = null;
                    return ['code' => 1, 'msg' => 'success', 'data' => $data];
                case "wechat":
                    if (!isset($param['method']) || !in_array($param['method'], ['JSAPI', 'APP'])) {
                        return ['code' => -1, 'msg' => '支付标识不存在'];
                    }
                    $notifyUrl = 'https://' . $_SERVER['HTTP_HOST'] . '/time/callback/mallWechat';
                    //设置参数
                    $wechat_pay = Pay::setDriver('WeChat')
                        ->basic('购买商品', $info->sn, $info->real_amount, $notifyUrl)
                        ->setMerchantType('mall');
                    if ($param['method'] == 'JSAPI') {
                        $wechat_pay->setOpenId($user->openid);
                    }
                    $options = $wechat_pay->create($param['method']);

                    $data['pay_alipay'] = null;
                    $data['pay_wechat'] = $options;
                    return ['code' => 1, 'msg' => 'success', 'data' => $data];

                case "currency":
                    if (md5($param['pay_password']) != $user->pay_password) {
                        return ['code' => -1, 'msg' => '支付密码错误'];
                    }
                    if ($user->assets->$account < $info->real_amount) {
                        return ['code' => -1, 'msg' => '余额不足'];
                    }
                    return self::operations($info, $user, $account, isset($param['is_behalf']) && $param['is_behalf'] == 1 ? $user->id : 0);
                default :
                    return ['code' => -1, 'msg' => '不支持的支付方式'];
            }
        } catch (\Exception $e) {
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function operations($info, $user, $account, $behalf_uid=0): array
    {
        if($info->pay_lock || $info->is_del){
            return ['code' => 1, 'msg' => 'success'];
        }
        $info->pay_lock = 1;
        $info->save();
        //开始拆单
        $children = json_decode($info->data, true);
        if (empty($children)) {
            return ['code' => -1, 'msg' => '订单异常，请稍后再试'];
        }

        $productNum = 0;
        parent::startTrans();
        try {
            $newOrderAll = [];
            $orderProductAll = [];
            foreach ($children['product'] as $item) {
                $business = Business::where('id', $item['business_id'])->field('id,type')->find();
                $uid = $behalf_uid ? $info->uid : $user->id;
                $order = [
                    'sn'              => 'P' . date('YmdHis') . $uid . rand(100000, 999999),
                    'out_trade_no'    => $info->sn,
                    'pay_way'         => $behalf_uid ? 'behalf' : $account,
                    'uid'             => $uid,
                    'pay_state'       => 2,
                    'pay_time'        => time(),
                    'remark'          => $item['business_remarks'],
                    'business_id'     => $item['business_id'],
                    'address_id'      => isset($children['address_id']) ? $children['address_id'] : 0,
                    'receiver'        => isset($info->receiver) ? $info->receiver : '',
                    'receiver_tel'    => isset($info->receiver_tel) ? $info->receiver_tel : '',
                    'province'        => isset($info->province) ? $info->province : '',
                    'city'            => isset($info->city) ? $info->city : '',
                    'district'        => isset($info->district) ? $info->district : '',
                    'address_details' => isset($info->address_details) ? $info->address_details : '',
                    'freight'         => $item['business_freight'],
                    'total_amount'    => $info->is_prize ? 0 : $item['business_total_amount'],
                    'real_amount'     => $info->is_prize ? 0 : $item['business_real_amount'],
                    'profit'          => $info->is_prize ? 0 : $item['business_profit'],
                    'vip_profit'      => $info->is_prize ? 0 : $item['business_vip_profit'],
                    'cost'            => $info->is_prize ? 0 : $item['business_cost'],
                    'currency'        => $info->is_prize ? 0 : $item['business_currency'],
                    'is_prize'        => $info->is_prize,
                    'prize_record_id' => $info->prize_record_id,
                    'status'          => $business['type'] == 1 ? 2 : 6,
                    'order_type'      => $info->order_type,
                    'order_mode'      => $business['type'],
                    'category'        => $info->category,
                    'is_life'         => $info->is_life,
                    'life_number'     => isset($info->life_number) ? $info->life_number : '',
                    'behalf_uid'      => $behalf_uid,
                    'cate_2'          => isset($item['children'][0]['cate_2']) ? $item['children'][0]['cate_2'] : 0
                ];
                $newOrder = Order::create($order);
                if($newOrder->prize_record_id){
                    PrizeRecord::where('id', $info->prize_record_id)->save(['status'=>1, 'order_id'=>$newOrder->id]);
                }

                //如果是线下订单，需要生成核销码
                if ($newOrder->order_mode == 2) {
                    $newOrder->write_off_code = strtoupper($newOrder->id . generateCode(4) . $user->id);
                    $newOrder->save();
                }

                //合约专区利润进入分红池
                if ($newOrder->order_type == 9) {
                    ContractBonusPoolRecord::addBonusPoolRecord($newOrder);
                }

                $product_info = '';
                foreach ($item['children'] as $child) {
                    $child['order_id'] = $newOrder->id;
                    $child['uid'] = $user->id;
                    $child['give_red_coin'] = ProductSpecValue::where('id', $child['spec_value_id'])->value('give_red_coin') ?? 0;
                    $orderProductAll[] = $child;
                    $newOrderAll[] = $newOrder;
                    $product_info .= $child['title'] . ' * ' . $child['num'] . '；';
                    $productNum += $child['num'];
                }
                $newOrder->product_info = $product_info;
                $newOrder->save();

                //累加统计
                Event::trigger('BusinessCensus', [
                    'id'    => $item['business_id'],
                    'total' => $item['business_real_amount'],
                    'type'  => 'census'
                ]);
                //资金流水
                Event::trigger('BusinessFundsFlow', [
                    'order' => $newOrder,
                    'type'  => 'add'
                ]);
            }
            (new OrderProduct())->insertAll($orderProductAll);

            $discount_alert['amount'] = '';
            $discount_alert['explain'] = '';
            foreach ($newOrderAll as $order) {
                $user->consume_total += $order->real_amount;
                $user->save();
            }

            if (!in_array($account, ['wechat', 'alipay'])) {
                Account::getInstance()->basics($user->id, $account, $info->real_amount, '购买商品', '-')->setOrder($info->id)->createNormal();
            }
            //根据订单类型处理后续

            $alert = '';
            $share_url = '';
            $share_amount = 0;
            $level_id = 0;
            switch ($info->order_type) {
                case 1:
                    break;
                default:
                    break;
            }
            if($user->month_consume == 0){
                $user->consume_count ++;
                $user->month_consume = 1;
                $user->save();

                Bonus::bonusEntry($user->id, $user->consume_count, $info);
            }

            $info->is_del = 1;
            $info->save();

            parent::commit();

            $data = [
                'alert' => $alert, 
                'discount_alert' => $discount_alert, 
                'share_url' => $share_url, 
                'level_id' => $level_id,
                'share_amount' => $share_amount
            ];


            //发送微信模板消息
            //$tplData = [
            //    'character_string1' => ['value' => $info->sn, 'color' => '#173177'],//订单编号
            //    'time4' => ['value' => date("Y-m-d H:i:s"), 'color' => '#173177'],//支付时间
            //];
            //(new WxTpl())->send($tplData, $user->gzh_openid, config('pay')['wx_tpl']['order_pay'], '/order/pages/orderDetail/index?id='.$newOrderId);

            return ['code' => 1, 'msg' => '支付成功', 'data' => $data];
        } catch (\Exception $e) {
            parent::rollback();
            Logs::exception($e);
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    /**
     * @param $param
     * @param $user
     * @return array
     * 原点 2023年1月4日14:50:07 提交订单
     */
    public static function submit($param, $user): array
    {
        try {
            $address = [];
            if (!$param['is_life']) {

                foreach ($param['product'] as &$product){
                    $business = Business::find($product['business_id']);
                    $product['business_address_details'] = $business->full_address;
                    if($business['type'] == 1){
                        if (!isset($param['address_id']) || !$param['address_id']) {
                            return ['code' => -1, 'msg' => '请选择收货地址'];
                        }
                        $address = Address::where('id', $param['address_id'])->find();
                        if (empty($address)) {
                            return ['code' => -1, 'msg' => '收货地址错误，请重新选择'];
                        }
                    }
                }
            } else {
                if (!isset($param['life_number']) || !$param['life_number']) {
                    return ['code' => -1, 'msg' => $param['is_life'] == 1 ? '请填写相关手机号' : '请填写户号'];
                }
            }
            return self::setUnSplitOrder($param, $user, $address);
        } catch (\Exception $e) {
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function setUnSplitOrder($param, $user, $address)
    {
        //总运费
        $freightTotal = 0;
        $currencyTotal = 0;
        $chainBeanTotal = 0;
        $loveBeanTotal = 0;
        $vipIntegTotal = 0;
        $redCoinTotal = 0;
        $discountTotal = 0;
        $total = 0;
        $discountIds = [];
        $order_type = 0;
        $is_renewal = 0;
        $category = 1;
        $profitTotal = 0;
        $vipProfitTotal = 0;
        $costTotal = 0;
        $cate_2 = '';
        $is_prize = isset($param['is_prize']) && $param['is_prize'] == 1 ? 1 : 0;
        $prize_record_id = isset($param['prize_record_id']) ? $param['prize_record_id'] : 0;
        $product_info = '';
        foreach ($param['product'] as &$item) {
            $business_freight = 0;
            $business_total_amount = 0;
            $business_real_amount = 0;
            $business_profit = 0;
            $business_vip_profit = 0;
            $business_cost = 0;
            $business_currency = 0;
            $business_chainBean = 0;
            $business_loveBean = 0;
            $business_vipInteg = 0;
            $business_redCoin = 0;
            $business_deduct = 0;
            foreach ($item['children'] as &$children) {
                $product = Product::where(['id' => $children['pid'], 'status' => 1, 'is_del' => 0])
                    ->field('id,title,freight,cate_1,cate_2,cate_3,stock,sales')->find();
                if (empty($product)) {
                    return ['code' => -1, 'msg' => '商品《' . $product->title . '》已下架'];
                }
                $specValue = ProductSpecValue::where('id', $children['spec_value_id'])->find();
                if ($children['num'] <= 0) {
                    return ['code' => -1, 'msg' => '商品《' . $product->title . '》数量错误'];
                }
                if (empty($specValue) || $children['num'] > $specValue->stock) {
                    return ['code' => -1, 'msg' => '商品《' . $product->title . '/ ' . $children['sku_name'] . '》库存不足'];
                }
                if ($product->cate_1 == 9 && $category == 1) {
                    $category = 2;
                }
                //可抵扣账户
                $deductCurrency = $user->assets->currency >= $specValue->currency ? $specValue->currency : $user->assets->currency;
                $deductChainBean = $user->assets->chain_bean >= $specValue->chain_bean ? $specValue->chain_bean : $user->assets->chain_bean;
                $deductVipInteg = $user->assets->vip_integ >= $specValue->vip_integ ? $specValue->vip_integ : $user->assets->vip_integ;
                $deductRedCoin = $user->assets->red_coin >= $specValue->red_coin ? $specValue->red_coin : $user->assets->red_coin;
                $deductLoveBean = $user->assets->love_bean >= $specValue->love_bean ? $specValue->love_bean : $user->assets->love_bean;
                //完善订单商品信息

                $vip_price = $user->level_id == 1 && in_array($product->cate_1, [1,8,13]) ? $specValue->price : $specValue->vip_price;
                $children['vip_price'] = $vip_price;
                $children['currency'] = !empty($param['currencyOpen']) ? $deductCurrency : 0;
                $children['chain_bean'] = !empty($param['chainBeanOpen']) ? $deductChainBean : 0;
                $children['love_bean'] = !empty($param['loveBeanOpen']) ? $deductLoveBean : 0;
                $children['vip_integ'] = !empty($param['vipIntegOpen']) ? $deductVipInteg : 0;
                $children['red_coin'] = !empty($param['redCoinOpen']) ? $deductRedCoin : 0;
                $children['title'] = $product->title;
                $children['icon'] = $specValue->icon;
                $children['deduct'] = 0;
                $children['profit'] = $specValue->profit;
                $children['vip_profit'] = $specValue->vip_profit;
                $children['cost'] = $specValue->cost;
                $children['cate_2'] = $product->cate_2;
                $children['cate_3'] = $product->cate_3;
                //单个商品的总价格和总运费
                $productTotal = $vip_price * $children['num'];
                $productFreightTotal = $product->freight * $children['num'];
                //订单总价格，总运费累加
                if(!$is_prize){
                    $total += $productTotal;
                }
                $freightTotal += $productFreightTotal;
                //订单各种抵扣金额累加
                $currencyTotal += $children['currency'] * $children['num'];
                $chainBeanTotal += $children['chain_bean'] * $children['num'];
                $loveBeanTotal += $children['love_bean'] * $children['num'];
                $vipIntegTotal += $children['vip_integ'] * $children['num'];
                $redCoinTotal += $children['red_coin'] * $children['num'];
                //每个商家的各项元素累加

                $child_cost = $children['cost'] * $children['num'];
                $child_profit = $children['profit'] * $children['num'];
                $child_vip_profit = $children['vip_profit'] * $children['num'];
                $child_currency = $children['currency'] * $children['num'];
                $child_chain_bean = $children['chain_bean'] * $children['num'];
                $child_love_bean = $children['love_bean'] * $children['num'];
                $child_vip_integ = $children['vip_integ'] * $children['num'];
                $child_red_coin = $children['red_coin'] * $children['num'];
                $child_deduct = $children['deduct'];

                $business_cost += $child_cost;
                $business_freight += $productFreightTotal;
                $business_profit += $child_profit;
                $business_vip_profit += $child_vip_profit;
                $business_currency += $child_currency;
                $business_chainBean += $child_chain_bean;
                $business_loveBean += $child_love_bean;
                $business_vipInteg += $child_vip_integ;
                $business_redCoin += $child_red_coin;
                //计算抵扣券
                if ($children['discount_id']) {
                    $discount = UserProductDiscount::where(['id' => $children['discount_id'], 'status' => 1])->where('num', '>', 0)->find();
                    if (empty($discount)) {
                        return ['code' => -1, 'msg' => '商品《' . $product->title . '》抵扣券错误！'];
                    }
                    $children['deduct'] = $discount->amount;// * $children['num'];
                    $discountTotal += $discount->amount;// * $children['num'];
                    $discountIds[] = $discount->id;
                    $business_deduct += $children['deduct'];// * $children['num'];
                }
                //减少库存
                $specValue->stock = $specValue->stock - $children['num'];
                $specValue->save();

                //增加销量
                $product->sales = $product->sales + $children['num'];
                $product->stock = $product->stock - $children['num'];
                $product->save();

                $business_total_amount += $productTotal + $productFreightTotal;
                //$business_real_amount += ($productTotal + $productFreightTotal) - $currencyTotal - $chainBeanTotal - $vipIntegTotal- $redCoinTotal - $loveBeanTotal - $discountTotal;
                $business_real_amount += ($productTotal + $productFreightTotal) - $child_currency - $child_chain_bean - $child_vip_integ- $child_red_coin - $child_love_bean - $child_deduct;

                //定义订单类别
                $order_type = $product->cate_1;
                //判断是否可触发续约
                if ($product->cate_2 == 21) {
                    $is_renewal = 1;
                }

                if ($product->cate_2 == 14) {
                    $cate_2 = 14;
                }

                $product_info .= $children['title'] . ' * ' . $children['num'] .'；';
            }
            //赋值每个商家各种元素总和
            $item['business_freight'] = $business_freight;
            $item['business_total_amount'] = $business_total_amount;
            $item['business_real_amount'] = $business_real_amount;
            $item['business_profit'] = $business_profit;
            $item['business_vip_profit'] = $business_vip_profit;
            $item['business_cost'] = $business_cost;
            $item['business_currency'] = $business_currency;
            $item['business_chainBean'] = $business_chainBean;
            $item['business_loveBean'] = $business_loveBean;
            $item['business_vipInteg'] = $business_vipInteg;
            $item['business_redCoin'] = $business_redCoin;
            $item['business_deduct'] = $business_deduct;

            $profitTotal += $business_profit;
            $vipProfitTotal += $business_vip_profit;
            $costTotal += $business_cost;
        }

        parent::startTrans();

        try {
            $new = parent::create([
                'sn'              => 'T' . date('YmdHis') . $user->id . rand(100000, 999999),
                'uid'             => $user->id,
                'address_id'      => isset($param['address_id']) ? $param['address_id'] : 0,
                'expire_time'     => time() + 1800,
                'data'            => json_encode($param),
                'currency'        => $currencyTotal,
                'chain_bean'      => $chainBeanTotal,
                'love_bean'       => $loveBeanTotal,
                'vip_integ'       => $vipIntegTotal,
                'red_coin'        => $redCoinTotal,
                'deduct'          => $discountTotal,
                'freight'         => $freightTotal,
                'receiver'        => !empty($address) ? $address->nickname : '',
                'receiver_tel'    => !empty($address) ? $address->tel : '',
                'province'        => !empty($address) ? $address->province : '',
                'city'            => !empty($address) ? $address->city : '',
                'district'        => !empty($address) ? $address->district : '',
                'address_details' => !empty($address) ? $address->details : '',
                'total_amount'    => $total + $freightTotal,
                'real_amount'     => $is_prize ? 0 : $total + $freightTotal - $currencyTotal - $chainBeanTotal - $loveBeanTotal - $vipIntegTotal - $redCoinTotal - $discountTotal,
                'discount_ids'    => $discountIds ? implode(',', $discountIds) : '',
                'order_type'      => $order_type,
                'is_renewal'      => $is_renewal,
                'category'        => $category,
                'profit'          => $profitTotal,
                'vip_profit'      => $vipProfitTotal,
                'cost'            => $costTotal,
                'is_life'         => $param['is_life'],
                'life_number'     => isset($param['life_number']) ? $param['life_number'] : '',
                'cate_2'          => $cate_2,
                'order_mode'      => empty($address) ? 2 : 1,
                'is_prize'        => $is_prize,
                'prize_record_id' => $prize_record_id,
                'product_info'        => $product_info
            ]);
            $account = [];
            $amount = [];
            if ($currencyTotal > 0) {
                $account[] = 'currency';
                $amount[] = $currencyTotal;
            }
            if ($chainBeanTotal > 0) {
                $account[] = 'chain_bean';
                $amount[] = $chainBeanTotal;
            }
            if ($loveBeanTotal > 0) {
                $account[] = 'love_bean';
                $amount[] = $loveBeanTotal;
            }
            if ($vipIntegTotal > 0) {
                $account[] = 'vip_integ';
                $amount[] = $vipIntegTotal;
            }
            if ($redCoinTotal > 0) {
                $account[] = 'red_coin';
                $amount[] = $redCoinTotal;
            }
            if (!empty($account) && !empty($amount)) {
                Account::getInstance()->basics($user->id, $account, $amount, '商品抵扣', '-')->setOrder($new->id)->createNormal();
            }
            if (!empty($discountIds)) {
                //UserProductDiscount::update(['status' => 2, 'use_time' => time()], ['id' => $discountIds]);
                foreach ($discountIds as $discountId){
                    $dis = UserProductDiscount::find($discountId);
                    if($dis->num > 1){
                        $dis->num --;
                        $dis->save();
                    }else{
                        $dis->num = 0;
                        $dis->status = 2;
                        $dis->use_time = time();
                        $dis->save();
                    }
                }
            }

            $cart_id = Cache::get('productTemporaryCartId_' . $user->id);
            if ($cart_id) {
                ProductCart::whereIn('id', $cart_id)->delete();
                Cache::delete('productTemporaryCartId_' . $user->id);
            }
            Cache::delete('productTemporary_' . $user->id);

            parent::commit();
            return ['code' => 1, 'msg' => 'success', 'data' => $new->id];
        } catch (\Exception $e) {
            parent::rollback();
            return ['code' => -1, 'msg' => $e->getMessage()];
        }

    }

    public static function parseOrderData($data)
    {
        $product = [];
        foreach (json_decode($data, true)['product'] as $item) {
            foreach ($item['children'] as $child) {
                $product[] = [
                    'pid'       => $child['pid'],
                    'title'     => $child['title'],
                    'icon'      => $child['icon'],
                    'sku_name'  => $child['sku_name'],
                    'vip_price' => $child['vip_price'],
                    'num'       => $child['num'],
                    'cate_2'    => Product::where('id', $child['pid'])->value('cate_2')
                ];
            }
        }
        return $product;
    }

    /**
     * @param $param
     * @param $user
     * @return array
     * 原点 2022年1月8日16:43:09 订单相关操作
     */
    public static function edit($param, $user): array
    {
        parent::startTrans();
        try {
            $info = parent::where(['id' => $param['id'], 'uid' => $user->id, 'is_del' => 0])->find();
            if (empty($info)) {
                return ['code' => -1, 'msg' => '订单不存在'];
            }
            switch ($param['type']) {
                case 'clear': //取消订单
                    if ($info->getData('status') != 1 || $info->pay_state) {
                        return ['code' => -1, 'msg' => '订单已支付，无法取消'];
                    }
                    $info->is_del = 1;
                    $info->status = 7;
                    $info->cancel_time = time();
                    $info->save();

                    self::returnAccount($info);
                    parent::commit();
                    return ['code' => 1, 'msg' => '订单已取消'];
                case "receipt": //确认收货
                    if ($info->getData('status') != 3) {
                        return ['code' => -1, 'msg' => '此订单无需收货'];
                    }
                    self::receipt($info);

                    parent::commit();
                    return ['code' => 1, 'msg' => '已确认收货'];
                default:
                    return ['code' => -1, 'msg' => '加载失败'];

            }
        } catch (\Exception $e) {
            parent::rollback();
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public function products(): HasMany
    {
        return $this->hasMany(OrderProduct::class, 'order_id', 'id')->field('id,order_id,pid,title,num,sku_name,icon');
    }

    /**
     * 订单收货
     * @param $order
     * @param false $is_auto
     * @return array|bool
     */
    public static function receipt($order, $is_auto = false)
    {
        $order->status = 4;
        $order->receipt_time = time();
        if ($is_auto) $order->auto_receipt_time = time();

        $order->save();
        Event::trigger('BusinessCensus', [
            'id'    => $order->business_id,
            'total' => $order->real_amount,
            'type'  => 'recorded'
        ]);

        //资金流水
        Event::trigger('BusinessFundsFlow', [
            'order' => $order,
            'type'  => 'entry'
        ]);

        Event::trigger('UserTotal', $order);

        //赠送积分
        Event::trigger('GiveRedCoin', $order);

        return true;
    }

    /**
     * 自动取消【定时任务】
     * @return array
     */
    public static function autoCancel(): array
    {
        try {
            $time = time() - Config::where('name', 'task_order_cancel')->value('value');
            self::where(['status' => 1, 'is_del'=>0])->where('create_time', '<', $time)->select()->each(function ($item) {
                Db::transaction(function () use ($item){
                    $item->status = 7;
                    $item->is_del = 1;
                    $item->cancel_time = time();
                    $item->save();

                    self::returnAccount($item);
                });
            });
            return ['code' => 1, 'msg' => '订单超时未支付取消成功'];
        } catch (\Exception $e) {
            Log::write("订单超时未支付取消失败：".$e->getMessage());
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    /**
     * 订单取消返还账户
     * @param $order
     * @return bool
     * @throws \app\common\tool\account\AccountException
     */
    public static function returnAccount($order)
    {
        if($order->currency > 0){
            Account::getInstance()->basics($order->uid, 'currency', $order->currency, '订单取消退还爱贝', '+')->setOrder($order->id)->createNormal();
        }
        if($order->chain_bean > 0){
            Account::getInstance()->basics($order->uid, 'chain_bean', $order->chain_bean, '订单取消退还链豆', '+')->setOrder($order->id)->createNormal();
        }
        if($order->love_bean > 0){
            Account::getInstance()->basics($order->uid, 'love_bean', $order->love_bean, '订单取消退还爱豆', '+')->setOrder($order->id)->createNormal();
        }
        if($order->vip_integ > 0){
            Account::getInstance()->basics($order->uid, 'vip_integ', $order->vip_integ, '订单取消退还VIP积分', '+')->setOrder($order->id)->createNormal();
        }
        if($order->red_coin > 0){
            Account::getInstance()->basics($order->uid, 'red_coin', $order->red_coin, '订单取消退还红包币', '+')->setOrder($order->id)->createNormal();
        }

        return true;
    }

    /**
     * 自动收货【定时任务】
     * @return array
     */
    public static function autoReceipt(): array
    {
        try {
            $time = Config::where('name', 'task_order_receipt')->value('value');//临时设置发货后5分钟自动收货，上线后改为1296000（15天）
            self::where(['status' => 3])->where('post_time', '>', 0)->select()->each(function ($item) use ($time){
                if(time() - $item->getData('post_time') >= $time){
                    Db::transaction(function () use ($item) {
                        self::receipt($item, true);
                    });
                }
            });
            return ['code' => 1, 'msg' => '自动收货成功'];
        } catch (\Exception $e) {
            Log::write("自动收货失败：".$e->getMessage());
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    /**
     * 订单确认收货后（7天）的后续消费区奖励，VIP奖励等【定时任务】
     * @return array
     */
    public static function orderReward(): array
    {
        try {
            $time = Config::where('name', 'task_order_reward')->value('value');//临时设置确认收货后5分钟执行奖励，上线后改为604800（7天）
            self::where(['is_reward' => 0])->where('receipt_time', '>', 0)->select()->each(function ($item) use ($time){
                if(time() - $item->getData('receipt_time') >= $time){
                    Db::transaction(function () use ($item) {
                        if (!in_array($item->order_type, [2, 9])) {//消费区
                            if ($item->order_type == 1) {//VIP区
                                Event::trigger('VipAward', $item);
                            }
                            Event::trigger('ReferrerAward', $item);
                            Event::trigger('SupplyAward', $item);
                        }

                        $item->is_reward = 1;
                        $item->save();

                    });
                }

            });
            return ['code' => 1, 'msg' => '执行奖励成功'];
        } catch (\Exception $e) {
            Log::write("执行奖励失败：".$e->getMessage());
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    /**
     * 订单确认收货后的订单利润进入分红池【定时任务】
     * @return array
     */
    public static function orderPooled(): array
    {
        try {
            $time = Config::where('name', 'task_order_pooled')->value('value');//临时设置确认收货后5分钟执行入池操作，上线后改为604800（7天）
            self::where(['is_pooled' => 0])->where('receipt_time', '>', 0)->select()->each(function ($item) use ($time){
                if(time() - $item->getData('receipt_time') >= $time) {
                    Db::transaction(function () use ($item) {
                        if ($item->order_type == 9) {//合约专区的进入合约专区分红池 改为支付完之后就进入分红池
                            //ContractBonusPoolRecord::addBonusPoolRecord($item);
                        } elseif ($item->order_type != 2) {
                            BonusPoolRecord::addBonusPoolRecord($item);
                        }

                    });
                }
            });
            return ['code' => 1, 'msg' => '执行入池成功'];
        } catch (\Exception $e) {
            Log::write("执行入池失败：".$e->getMessage());
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    /**
     * 申请开票
     * @param $param
     * @param $user
     * @return array
     */
    public static function invoiceApply($param, $user): array
    {
        parent::startTrans();
        try {
            $order = self::find($param['order_id']);
            if(!$order || !$order->pay_time){
                return ['code' => -1, 'msg' => '订单不存在或订单尚未支付'];
            }
            if($order->invoice_status > 0){
                return ['code' => -1, 'msg' => '您已提交申请开票，请勿重复提交！'];
            }
            if($param['type'] == 2 && empty($param['tax_no'])){
                return ['code' => -1, 'msg' => '请填写税号'];
            }
            if($param['cate']==1){
                if(empty($param['email'])){
                    return ['code' => -1, 'msg' => '请填写邮箱地址'];
                }
            }else{
                if(empty($param['receiver'])){
                    return ['code' => -1, 'msg' => '请填写收件人'];
                }
                if(empty($param['mobile'])){
                    return ['code' => -1, 'msg' => '请填写手机号'];
                }
                if(empty($param['address'])){
                    return ['code' => -1, 'msg' => '请填写收件地址'];
                }
            }

            if($param['amount'] > $order->real_amount){
                return ['code' => -1, 'msg' => '开票金额不得大于订单金额'];
            }

            $param['uid'] = $user->id;
            $param['business_id'] = $order->business_id;

            OrderInvoice::create($param);

            $order->invoice_status = 1;
            $order->save();

            parent::commit();
            return ['code' => 1, 'msg' => '申请已提交，请耐心等待审核！'];
        } catch (\Exception $e) {
            parent::rollback();
            return ['code' => -1, 'msg' => $e->getMessage()];
        }
    }

    public static function getOrderedNum($uid, $product_id)
    {
        $ordered = 0;
        $orders = Order::where(['pay_state'=>0, 'uid'=>$uid, 'is_del'=>0])->column('data');
        if($orders){
            foreach ($orders as $order){
                $data = json_decode($order, true);
                foreach ($data['product'] as $product){
                    foreach ($product['children'] as $child){
                        if($child['pid'] == $product_id){
                            $ordered ++;
                        }
                    }
                }
            }
        }

        return $ordered;
    }
}
